home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK2.toast / Development Kits / Hardware / PCI Driver Development Kit / • Tools / Utility / LoadDriverTest 950518 / Src / AppleEventCore.c next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  24.8 KB  |  1,124 lines  |  [TEXT/MPCC]

  1. /*                                    AppleEventCore.c                            */
  2. /*
  3.  * AppleEventCore.c
  4.  * Copyright © 1988-94 Apple Computer Inc. All rights reserved.
  5.  * Note: a lot of these functions are not (yet) used.
  6.  */
  7. #include "AppleEventCore.h"
  8. #ifndef THINK_C /* Temp until headers stabalize */
  9. #include <AERegistry.h>
  10. #include <AppleTalk.h>
  11. #include <Gestalt.h>
  12. #include <Dialogs.h>
  13. #include <Errors.h>
  14. #include <Script.h>
  15. #include <TextUtils.h>
  16. #endif
  17.  
  18. #ifndef FALSE
  19. #define FALSE        0
  20. #define TRUE        1
  21. #endif
  22.  
  23. AECoreGlobals                    gAECoreGlobals;
  24. #define GLOBAL                    (gAECoreGlobals)
  25. Boolean                            gHasAppleEvents;
  26. static AEOpenAppHandlerFunc        gAEOpenAppHandlerFunc;
  27. static AEDocumentHandlerFunc    gAEOpenDocHandlerFunc;
  28. static AEDocumentHandlerFunc    gAEPrintDocHandlerFunc;
  29. static AEQuitAppHandlerFunc        gAEQuitAppHandlerFunc;
  30. static AEDoScriptHandlerFunc    gAEDoScriptHandlerFunc;
  31. static AEUnknownHandlerMsgFunc    gAEUnknownHandlerMsgFunc;
  32.  
  33. static pascal OSErr            AEOpenApplication(
  34.         const AppleEvent        *theEvent,
  35.         AppleEvent                *theReply,
  36.         long                    refCon
  37.     );
  38. static pascal OSErr            AEOpenDocument(
  39.         const AppleEvent        *theEvent,
  40.         AppleEvent                *theReply,
  41.         long                    refCon
  42.     );
  43. static pascal OSErr            AEPrintDocument(
  44.         const AppleEvent        *theEvent,
  45.         AppleEvent                *theReply,
  46.         long                    refCon
  47.     );
  48. static pascal OSErr            AEQuit(
  49.         const AppleEvent        *theEvent,
  50.         AppleEvent                *theReply,
  51.         long                    refCon
  52.     );
  53. static OSErr                AEOpenOrPrint(
  54.         const AppleEvent        *theEvent,
  55.         AppleEvent                *theReply,
  56.         long                    refCon,
  57.         AEDocumentHandlerFunc    aeDocumentHandlerFunc
  58.     );
  59. static pascal OSErr            AEUnknownHandler(
  60.         const AppleEvent        *theEvent,
  61.         AppleEvent                *theReply,
  62.         long                    refCon
  63.     );
  64. static pascal OSErr            AEDoScript(
  65.         const AppleEvent        *theEvent,
  66.         AppleEvent                *theReply,
  67.         long                    refCon
  68.     );
  69. static void                    AEGetMyZone(
  70.         Str32                    zoneName
  71.     );
  72.  
  73. /*
  74.  * Define a table used to install event handlers.
  75.  */
  76. const static AEHandlerDefRec    gAEHandlerDefs[] = {
  77.     { kCoreEventClass,    kAEStartRecording,            AEIgnore                    },
  78.     { kCoreEventClass,    kAEStopRecording,            AEIgnore                    },
  79.     { kCoreEventClass,    kAENotifyRecording,            AEIgnore                    },
  80.     { kCoreEventClass,    kAENotifyStopRecording,        AEIgnore                    },
  81.     { kCoreEventClass,    kAENotifyStartRecording,    AEIgnore                    },
  82.     { kCoreEventClass,    kAEOpenApplication,            AEOpenApplication            },
  83.     { kCoreEventClass,    kAEOpenDocuments,            AEOpenDocument                },
  84.     { kCoreEventClass,    kAEPrintDocuments,            AEPrintDocument                },
  85.     { kCoreEventClass,    kAEQuitApplication,         AEQuit                        },
  86.     { 0,                0,                            NULL                        }
  87. };
  88.  
  89. #define UNUSED(what)    (what)
  90.  
  91. static void                    ClearMemory(
  92.         register void            *ptr,
  93.         register long            size
  94.     );
  95. #define CLEAR(rec)    (ClearMemory(&rec, sizeof rec))
  96. static void                    pstrcpy(
  97.         StringPtr                dst,
  98.         ConstStr255Param        src
  99.     );
  100. static void                    pstrcat(
  101.         StringPtr                dst,
  102.         ConstStr255Param        src
  103.     );
  104.  
  105. pascal OSErr
  106. InitializeAppleEvents(
  107.         AEOpenAppHandlerFunc    aeOpenAppHandlerFunc,
  108.         AEDocumentHandlerFunc    aeOpenDocHandlerFunc,
  109.         AEDocumentHandlerFunc    aePrintDocHandlerFunc,
  110.         AEQuitAppHandlerFunc    aeQuitAppHandlerFunc,
  111.         AEDoScriptHandlerFunc    aeDoScriptHandlerFunc,
  112.         AEUnknownHandlerMsgFunc    aeUnknownHandlerMsgFunc,
  113.         long                    refCon
  114.     )
  115. {
  116.         long                    response;
  117.         OSErr                    status;
  118.  
  119.         status = Gestalt(gestaltAppleEventsAttr, &response);
  120.         gHasAppleEvents = (
  121.                     status == noErr
  122.                     && (response & (1L << gestaltAppleEventsPresent) != 0)
  123.                 );
  124.         status = (gHasAppleEvents == FALSE) ? gestaltUndefSelectorErr : noErr;
  125.         if (status == noErr) {
  126.             gAEOpenAppHandlerFunc = aeOpenAppHandlerFunc;
  127.             gAEOpenDocHandlerFunc = aeOpenDocHandlerFunc;
  128.             gAEPrintDocHandlerFunc = aePrintDocHandlerFunc;
  129.             gAEQuitAppHandlerFunc = aeQuitAppHandlerFunc;
  130.             gAEDoScriptHandlerFunc = aeDoScriptHandlerFunc;
  131.             gAEUnknownHandlerMsgFunc = aeUnknownHandlerMsgFunc;
  132.             status = AEInstallEventHandlers(
  133.                         (AEHandlerDefPtr) gAEHandlerDefs, refCon);
  134.         }
  135.         if (status == noErr && aeDoScriptHandlerFunc != NULL) {
  136.             status = AEInstallEventHandler(
  137.                         kAEMiscStandards,
  138.                         kAEDoScript,
  139.                         NewAEEventHandlerProc(AEDoScript),
  140.                         0,                        /* No refCon                */
  141.                         FALSE                    /* Not system event            */
  142.             );
  143.         }
  144.         if (status == noErr && aeUnknownHandlerMsgFunc != NULL) {
  145.             status = AEInstallEventHandler(
  146.                         typeWildCard,
  147.                         typeWildCard,
  148.                         NewAEEventHandlerProc(AEUnknownHandler),
  149.                         0,                        /* No refCon                */
  150.                         FALSE                    /* Not system event            */
  151.             );
  152.         }
  153.         return (status);
  154. }
  155.  
  156. /*
  157.  * Initialize for apple events: and setup the handler callbacks so we process
  158.  * events. Fail if a handler can't be installed. The caller should check
  159.  * gHasAppleEvents to see if they are actually present.
  160.  */
  161. pascal OSErr
  162. AEInstallEventHandlers(
  163.         AEHandlerDefPtr            aeHandlerDefPtr,
  164.         long                    refCon
  165.     )
  166. {
  167.         OSErr                    status;
  168.  
  169.         status = noErr;
  170.         if (aeHandlerDefPtr != NULL) {
  171.             while (status == noErr && aeHandlerDefPtr->procPtr != NULL) {
  172.                 status = AEInstallEventHandler(
  173.                             aeHandlerDefPtr->eventClass,
  174.                             aeHandlerDefPtr->eventID,
  175.                             NewAEEventHandlerProc(aeHandlerDefPtr->procPtr),
  176.                             refCon,
  177.                             FALSE                    /* Not system event            */
  178.                 );
  179.                 ++aeHandlerDefPtr;
  180.             }
  181.         }
  182.         return (status);
  183. }
  184.  
  185. /*
  186.  * Initialize for apple events: and setup the coercion callbacks so we process
  187.  * events. Fail if a handler can't be installed. The caller should check
  188.  * gHasAppleEvents to see if they are actually present.
  189.  */
  190. pascal OSErr
  191. AEInstallCoercionHandlers(
  192.         AECoercionDefPtr        aeCoercionDefPtr,
  193.         long                    refCon
  194.     )
  195. {
  196.         OSErr                    status;
  197.  
  198.  
  199.         status = noErr;
  200.         if (aeCoercionDefPtr != NULL) {
  201.             while (aeCoercionDefPtr->procPtr != NULL) {
  202. /* Is this correct: without the cast, it doesn't compile on 68000 */
  203.                 status = AEInstallCoercionHandler(
  204.                             aeCoercionDefPtr->fromType,
  205.                             aeCoercionDefPtr->toType,
  206.                             (AECoercionHandlerUPP) NewAECoercePtrProc(aeCoercionDefPtr->procPtr),
  207.                             refCon,
  208.                             FALSE,                    /* Pass data                */
  209.                             FALSE                    /* Not system handler        */
  210.                         );
  211.                 ++aeCoercionDefPtr;
  212.             }
  213.         }
  214.         return (status);
  215. }
  216.  
  217. /*
  218.  * Open (initial double-click) the application. The handler is optional.
  219.  */
  220. static pascal OSErr
  221. AEOpenApplication(
  222.         const AppleEvent        *theEvent,
  223.         AppleEvent                *theReply,
  224.         long                    refCon
  225.     )
  226. {
  227.         OSErr                    status;
  228.         
  229.         status = AEHandlerSetup(theEvent, theReply, refCon);
  230.         if (status == noErr)
  231.             status = AEGotRequiredParams(theEvent);
  232.         if (status == noErr && gAEOpenAppHandlerFunc != NULL)
  233.             status = (*gAEOpenAppHandlerFunc)(refCon);    /* Application specific    */
  234.         GLOBAL.currentEventIsAppleEvent = FALSE;
  235.         return (status);        
  236. }
  237.  
  238.  
  239. /*
  240.  * Open a document. This can be called at application setup, but it can also
  241.  * be called by dropping a document on the application icon.
  242.  */
  243. static pascal OSErr
  244. AEOpenDocument(
  245.         const AppleEvent        *theEvent,
  246.         AppleEvent                *theReply,
  247.         long                    refCon
  248.     )
  249. {
  250.         OSErr                    status;
  251.         
  252.         status = AEOpenOrPrint(theEvent, theReply, refCon, gAEOpenDocHandlerFunc);
  253.         return (status);
  254. }
  255.  
  256. /*
  257.  * Print a document. This can be called at application setup, but it can also
  258.  * be called by dropping a document on the application icon.
  259.  */
  260. static pascal OSErr
  261. AEPrintDocument(
  262.         const AppleEvent        *theEvent,
  263.         AppleEvent                *theReply,
  264.         long                    refCon
  265.     )
  266. {
  267.         OSErr                    status;
  268.  
  269.         status = AEOpenOrPrint(theEvent, theReply, refCon, gAEPrintDocHandlerFunc);
  270.         return (status);
  271. }
  272.  
  273. /*
  274.  * This is the common handler for AppleEvent open document and print document.
  275.  * The actual work is done by application-specific code.
  276.  */
  277. static OSErr
  278. AEOpenOrPrint(
  279.         const AppleEvent        *theEvent,
  280.         AppleEvent                *theReply,
  281.         long                    refCon,
  282.         AEDocumentHandlerFunc    aeDocumentHandlerFunc
  283.     )
  284. {
  285.         OSErr                    status;
  286.         AEDesc                    theDesc;
  287.         long                    numberOfFiles;
  288.         long                    iFile;
  289.         AEKeyword                ignoredKeyWord;
  290.         DescType                ignoredType;
  291.         Size                    ignoredSize;
  292.         FSSpec                    theFSS;
  293.         
  294.         theDesc.dataHandle = NULL;;
  295.         status = (aeDocumentHandlerFunc == NULL) ? errAEEventNotHandled : noErr;
  296.         if (status == noErr)
  297.             status = AEHandlerSetup(theEvent, theReply, refCon);
  298.         if (status == noErr)
  299.             status = AEGetParamDesc(theEvent, keyDirectObject, typeAEList, &theDesc);
  300.         if (status == noErr)
  301.             status = AEGotRequiredParams(theEvent);
  302.         if (status == noErr)
  303.             status = AECountItems(&theDesc, &numberOfFiles);
  304.         for (iFile = 1; status == noErr && iFile <= numberOfFiles; iFile++) {
  305.             status = AEGetNthPtr(
  306.                         &theDesc,
  307.                         iFile,
  308.                         typeFSS,
  309.                         &ignoredKeyWord,
  310.                         &ignoredType,
  311.                         (Ptr) &theFSS,
  312.                         sizeof theFSS,
  313.                         &ignoredSize
  314.                     );
  315.             if (status == noErr) {
  316.                 /*
  317.                  * Note that an error from the handler will terminate all files.
  318.                  */
  319.                 status = (*aeDocumentHandlerFunc)(&theFSS, refCon);
  320.             }
  321.         }
  322.         (void) AEDisposeDesc(&theDesc);
  323.         GLOBAL.currentEventIsAppleEvent = FALSE;
  324.         return (status);
  325. }
  326.  
  327. static pascal OSErr
  328. AEQuit(
  329.         const AppleEvent        *theEvent,
  330.         AppleEvent                *theReply,
  331.         long                    refCon
  332.     )
  333. {
  334.         OSErr                    status;
  335.  
  336.         status = (gAEQuitAppHandlerFunc == NULL) ? errAEEventNotHandled : noErr;
  337.         if (status == noErr)
  338.             status = AEHandlerSetup(theEvent, theReply, refCon);
  339.         if (status == noErr)
  340.             status = AEGotRequiredParams(theEvent);
  341.         status = (*gAEQuitAppHandlerFunc)(refCon);
  342.         GLOBAL.currentEventIsAppleEvent = FALSE;
  343.         return (status);        
  344. }
  345.                 
  346. /*
  347.  * This handler is called for "scripting on/off" events. They are ignored.
  348.  */
  349. pascal OSErr
  350. AEIgnore(
  351.         const AppleEvent        *theEvent,
  352.         AppleEvent                *theReply,
  353.         long                    refCon
  354.     )
  355. {
  356.         UNUSED(theEvent);
  357.         UNUSED(theReply);
  358.         UNUSED(refCon);
  359.         GLOBAL.currentEventIsAppleEvent = FALSE;
  360.         return (noErr);
  361. }
  362.  
  363. /*
  364.  * Unknown events go here. If the application provides an alert, call it.
  365.  * The initializer has provided a handler functions.
  366.  */
  367. static pascal OSErr
  368. AEUnknownHandler(
  369.         const AppleEvent        *theEvent,
  370.         AppleEvent                *theReply,
  371.         long                    refCon
  372.     )
  373. {
  374.         OSErr                    status;
  375.         OSType                    eventClass;
  376.         OSType                    eventID;
  377.         OSType                    typeCode;
  378.         Size                    actualSize;
  379.         Str255                    work;
  380.         
  381.         status = AEHandlerSetup(theEvent, theReply, refCon);
  382.         if (status == noErr) {
  383.             status = AEGetAttributePtr(
  384.                 theEvent,
  385.                 keyEventClassAttr,
  386.                 typeType,
  387.                 &typeCode,
  388.                 (Ptr) &eventClass,
  389.                 sizeof(eventClass),
  390.                 &actualSize
  391.             );
  392.         }
  393.         if (status == noErr) {
  394.             AEGetAttributePtr(
  395.                 theEvent,
  396.                 keyEventIDAttr,
  397.                 typeType,
  398.                 &typeCode,
  399.                 (Ptr) &eventID,
  400.                 sizeof(eventID),
  401.                 &actualSize
  402.             );
  403.         }
  404.         if (status == noErr) {
  405.             pstrcpy(work, "\pUnknown AppleEvent. Class ");
  406.             BlockMoveData(&eventClass, &work[work[0] + 1], sizeof (OSType));
  407.             work[0] += sizeof (OSType);
  408.             pstrcat(work, "\p, ID ");
  409.             BlockMoveData(&eventID, &work[work[0] + 1], sizeof (OSType));
  410.             work[0] += sizeof (OSType);
  411.             (*gAEUnknownHandlerMsgFunc)(work);
  412.         }
  413.         GLOBAL.currentEventIsAppleEvent = FALSE;
  414.         return (errAEHandlerNotFound);        
  415. }
  416.  
  417. /*
  418.  * This processes the Do Script event. The application provided a handler.
  419.  */
  420. static pascal OSErr
  421. AEDoScript(
  422.         const AppleEvent        *theEvent,
  423.         AppleEvent                *theReply,
  424.         long                    refCon
  425.     )
  426. {
  427.         CharsHandle                scriptHandle;
  428.         OSErr                    status;
  429.         
  430.         scriptHandle = NULL;
  431.         status = AEHandlerSetup(theEvent, theReply, refCon);
  432.         if (status == noErr)
  433.             status = AEGetChars(theEvent, keyDirectObject, &scriptHandle);
  434.         if (status == noErr)
  435.             status = AEGotRequiredParams(theEvent);
  436.         if (status == noErr) {
  437.             /*
  438.              * Make sure there's a null trailer.
  439.              */
  440.             status = PtrAndHand("", (Handle) scriptHandle, 1);
  441.         }
  442.         if (status == noErr) {
  443.             MoveHHi((Handle) scriptHandle);
  444.             HLock((Handle) scriptHandle);
  445.             status = (*gAEDoScriptHandlerFunc)(
  446.                         (Ptr) *scriptHandle,
  447.                         GetHandleSize((Handle) scriptHandle),
  448.                         theReply,
  449.                         refCon
  450.                 );
  451.         }
  452.         if (scriptHandle != NULL) {
  453.             DisposeHandle((Handle) scriptHandle);
  454.             scriptHandle = NULL;
  455.         }
  456.         GLOBAL.currentEventIsAppleEvent = FALSE;
  457.         return (status);
  458. }
  459.  
  460. /*
  461.  * Utilities
  462.  */
  463. /*
  464.  * Build an AppleEvent descriptor for a target address. The addressMode parameter
  465.  * chooses the target:
  466.  *    kSelfCurrentProcess    direct calls to this application (for scripting)
  467.  *    kSelfUsingPSN        event-loop based calls to this application (script debug)
  468.  *    kOtherApplication    dialog-based calls to an external application.
  469.  */
  470. pascal OSErr
  471. AEMakeTargetAddress(
  472.         AETargetAddressType        aeTargetAddressType,
  473.         AEDesc                    *theAddress,
  474.         StringPtr                targetName
  475.     )
  476. {
  477.         OSErr                    status;
  478.         ProcessSerialNumber        myPSN;
  479.         StringPtr                theTarget;
  480.         
  481.         theTarget = "\p";            /* Bogus initialize for MetroWerks            */
  482.         switch (aeTargetAddressType) {
  483.         case kAETargetSelfCurrentProcess:
  484.             /*
  485.              * Note that, if you use this case, the Apple Event
  486.              * Manager will bypass the event loop and call your
  487.              * handlers directly.
  488.              */
  489.             myPSN.highLongOfPSN = 0;
  490.             myPSN.lowLongOfPSN = kCurrentProcess;
  491.             theTarget = "\pLocal direct linkage"; 
  492.             goto makeDescriptor;
  493.         case kAETargetSelfUsingPSN:
  494.             /*
  495.              * This case always calls through the event loop.
  496.              */
  497.             status = GetCurrentProcess(&myPSN);
  498.             theTarget = "\pLocal linkage through event loop"; 
  499.             if (status == noErr) {
  500. makeDescriptor:    status = AECreateDesc(
  501.                         typeProcessSerialNumber,
  502.                         (Ptr) &myPSN,
  503.                         sizeof (ProcessSerialNumber),
  504.                         theAddress
  505.                     );
  506.             }
  507.             break;
  508.         case kAETargetOtherApplication:
  509.             status = AEBrowseForTarget(
  510.                         NULL, NULL, NULL, NULL, theAddress, theTarget);
  511.             break;
  512.         }
  513.         if (status == noErr && targetName != NULL)
  514.             BlockMoveData(theTarget, targetName, theTarget[0] + 1);
  515.         return (status);
  516. }
  517.  
  518. /*
  519.  * Call the PPC Toolbox browser to locate a target application.
  520.  *    dialogPrompt        -> "Choose a program to link to" if NULL
  521.  *    listHeader            -> "Programs"
  522.  *    theAddress            <- the result
  523.  *    targetName            <- the application name text for error alerts
  524.  */
  525. pascal OSErr
  526. AEBrowseForTarget(
  527.         ConstStr255Param        dialogPrompt,
  528.         ConstStr255Param        listHeader,
  529.         PPCFilterUPP            filterProcUPP,
  530.         ConstStr255Param        locNBPType,                
  531.         AEDesc                    *theAddress,
  532.         StringPtr                targetName
  533.     )
  534. {
  535.         LocationNameRec            theLoc;
  536.         PortInfoRec                theRec;
  537.         OSErr                    status;
  538.         TargetID                theID;
  539.  
  540.         status = PPCBrowser(
  541.                     dialogPrompt,
  542.                     listHeader,
  543.                     FALSE,            /* No default        */
  544.                     &theLoc,
  545.                     &theRec,
  546.                     filterProcUPP,    
  547.                     locNBPType
  548.                 );
  549.         if (status == noErr) {
  550.             /*
  551.              * Create a target descriptor
  552.              */
  553.             BlockMoveData(
  554.                 theRec.name.name,
  555.                 targetName,
  556.                 theRec.name.name[0] + 1
  557.             );
  558.             theID.name = theRec.name;
  559.             theID.location = theLoc;
  560.             status = AECreateDesc(
  561.                         typeTargetID,
  562.                         (Ptr) &theID,
  563.                         sizeof(theID),
  564.                         theAddress
  565.                     );
  566.         }
  567.         if (status == noErr)
  568.             ParamText(targetName, "\p", "\p", "\p");
  569.         return (status);
  570. }
  571.  
  572. /*
  573.  * Call IPCListPorts to locate a target application.
  574.  *    machineName            -> the machine to look for
  575.  *    targetNameVector    -> a vector (NULL terminated) of application name strings.
  576.  *    theAddress            <- the result
  577.  *    targetName            <- the application name text for error alerts
  578.  */
  579. pascal OSErr
  580. AELocateTarget(
  581.         ConstStr255Param        machineName,
  582.         const StringPtr            *targetNameVector,
  583.         AEDesc                    *theAddress,
  584.         StringPtr                actualTargetName
  585.     )
  586. {
  587.         LocationNameRec            locationNameRec;
  588.         OSErr                    status;
  589.         TargetID                theID;
  590.         IPCListPortsPBRec        ipcListPortsPBRec;
  591.         PPCPortRec                ppcPortRec;
  592.         PortInfoRec                portInfoRec;
  593.         short                    i;
  594.         short                    j;
  595. #define IPC        (ipcListPortsPBRec)
  596. #define LOC        (locationNameRec)
  597. #define PORT    (ppcPortRec)
  598. #define INFO    (portInfoRec)
  599.  
  600.         CLEAR(PORT);
  601.         PORT.nameScript = smRoman;
  602.         pstrcpy(PORT.name, "\p=");
  603.         PORT.portKindSelector = ppcByString;
  604.         pstrcpy(PORT.u.portTypeStr, "\p=");
  605.         CLEAR(LOC);
  606.         LOC.locationKindSelector = ppcNBPLocation;
  607.         pstrcpy(LOC.u.nbpEntity.objStr, (void *) machineName);
  608.         pstrcpy(LOC.u.nbpEntity.typeStr, "\pPPCToolBox");
  609.         AEGetMyZone(LOC.u.nbpEntity.zoneStr);
  610.         status = noErr;
  611.         for (i = 0; status == noErr; i++) {
  612.             CLEAR(IPC);
  613.             IPC.startIndex = i;
  614.             IPC.requestCount = 1;
  615.             IPC.portName = &PORT;
  616.             IPC.locationName = &LOC;
  617.             IPC.bufferPtr = &portInfoRec;
  618.             status = IPCListPorts(&IPC, FALSE);
  619.             if (status == noErr) {
  620.                 BlockMoveData(
  621.                     INFO.name.name,
  622.                     actualTargetName,
  623.                     INFO.name.name[0] + 1
  624.                 );
  625.                 for (j = 0; targetNameVector[j] != NULL; j++) {
  626.                     if (EqualString(
  627.                             actualTargetName, targetNameVector[j], FALSE, FALSE)) {
  628.                         theID.name = INFO.name;
  629.                         theID.location = LOC;
  630.                         status = AECreateDesc(
  631.                                 typeTargetID,
  632.                                 (Ptr) &theID,
  633.                                 sizeof(theID),
  634.                                 theAddress
  635.                             );
  636.                         goto exit;
  637.                     }
  638.                 }
  639.             }
  640.         }
  641. exit:    return (status);
  642. #undef IPC
  643. #undef LOC
  644. #undef PORT
  645. #undef INFO
  646. }
  647.  
  648. /*
  649.  * This should be called before doing any user-interaction, such as alerts
  650.  * or dialogs. It returns FALSE if interaction is blocked at this time.
  651.  * The application should provide an idle function UPP. For example,
  652.  *
  653.  *        pascal Boolean
  654.  *        MyAEIdleProc(
  655.  *                const EventRecord        *theEventPtr,
  656.  *                long                    *sleepTime,
  657.  *                RgnHandle                *mouseRgn
  658.  *            )
  659.  *        {
  660.  *                if (theEventPtr->what == kHighLevelEvent)
  661.  *                    return (TRUE);
  662.  *                else {
  663.  *                    *sleepTime = ProcessThisEvent(theEventPtr);
  664.  *                    return (FALSE);
  665.  *                }
  666.  *        }        
  667.  */
  668. pascal Boolean
  669. AEInteractionOK(
  670.         AEIdleUPP                aeIdleUPP
  671.     )
  672. {
  673.         Boolean                    result;
  674.         OSErr                    status;
  675.  
  676.         if (GLOBAL.currentEventIsAppleEvent == FALSE)
  677.             result = TRUE;
  678.         else {
  679.             status = AEInteractWithUser(0, NULL, aeIdleUPP);
  680.             result = (status == noErr);
  681.         }
  682.         return (result);
  683. }
  684.  
  685. /*
  686.  * AEGotRequiredParams fails if not all required parameters have been extracted.
  687.  * Call this after retrieving all required parameters before actually processing
  688.  * the event. This sets gCurrentAEStatus to noErr if it succeeds.
  689.  *
  690.  * If required parameters remain, return errAEParamMissed.
  691.  */
  692. pascal OSErr
  693. AEGotRequiredParams(
  694.         const AppleEvent        *theEvent
  695.     )
  696. {
  697.         DescType                descType;
  698.         Size                    actualSize;
  699.         OSErr                    status;
  700.         
  701.         status = AEGetAttributePtr(
  702.                 theEvent,
  703.                 keyMissedKeywordAttr,
  704.                 typeWildCard,
  705.                 &descType,
  706.                 NULL,
  707.                 0,
  708.                 &actualSize
  709.             );
  710.         if (status == errAEDescNotFound) {
  711.             GLOBAL.currentAEStatus = noErr;
  712.             status = noErr;
  713.         }
  714.         else {
  715.             status = errAEParamMissed;
  716.         }
  717.         return (status);
  718. }
  719.  
  720. /*
  721.  * All apple events call this function initially to store common information.
  722.  */
  723. pascal OSErr
  724. AEHandlerSetup(
  725.         const AppleEvent        *theEvent,
  726.         AppleEvent                *theReply,
  727.         long                    refCon
  728.     )
  729. {
  730.         OSErr                    status;
  731.         DescType                actualType;
  732.         Size                    actualSize;
  733.  
  734.         /*
  735.          * Here's where we add the Frontier "shared script" cancel handler.
  736.          */
  737.         GLOBAL.currentAEEvent = theEvent;
  738.         GLOBAL.currentAEReply = theReply;
  739.         GLOBAL.currentAERefCon = refCon;
  740.         GLOBAL.currentAEStatus = errAEEventNotHandled;
  741.         GLOBAL.currentEventIsAppleEvent = TRUE;
  742.         /*
  743.          * Try to extract the class and type parameters, then switch on the
  744.          * event and process what we can. Note that GLOBAL.currentAEStatus is
  745.          * initializad to an error code: the final caller must set the status to
  746.          * noErr if the event was correctly handled. Normally, this is done
  747.          * by AEGotRequiredParams
  748.          */
  749.         status = AEGetAttributePtr(
  750.                     theEvent,
  751.                     keyEventClassAttr,
  752.                     typeType,
  753.                     &actualType,
  754.                     (Ptr) &GLOBAL.currentAEEventClass,
  755.                     sizeof GLOBAL.currentAEEventClass,
  756.                     &actualSize
  757.                 );
  758.         if (status == noErr) {
  759.             status = AEGetAttributePtr(
  760.                         theEvent,
  761.                         keyEventIDAttr,
  762.                         typeType,
  763.                         &actualType,
  764.                         (Ptr) &GLOBAL.currentAEEventID,
  765.                         sizeof GLOBAL.currentAEEventID,
  766.                         &actualSize
  767.                     );
  768.         }
  769.         if (status == noErr) {
  770.             status = AEGetAttributePtr(
  771.                     theEvent,
  772.                     keyInteractLevelAttr,
  773.                     typeInteger,
  774.                     &actualType,
  775.                     (Ptr) &GLOBAL.currentAEIntractionLevel,
  776.                     sizeof GLOBAL.currentAEIntractionLevel,
  777.                     &actualSize
  778.             );
  779.         }
  780.         return (status);
  781. }
  782.  
  783. /*
  784.  * These functions get and set data in the AppleEvent. They are only needed
  785.  * if we intend to receive events.
  786.  */
  787.  
  788. /*
  789.  * AEGetShort extracts a signed short integer from the parameter list.
  790.  * Return noErr on success, errAEDescNotFound if the parameter was missing.
  791.  */
  792. pascal OSErr
  793. AEGetShort(
  794.         const AppleEvent        *theEvent,
  795.         DescType                parameterKey,
  796.         short                    *result
  797.     )
  798. {
  799.         OSErr                    status;
  800.         Size                    actualSize;
  801.         DescType                actualType;
  802.  
  803.         status = AEGetParamPtr(
  804.                     theEvent,
  805.                     parameterKey,
  806.                     typeSMInt,
  807.                     &actualType,
  808.                     (Ptr) result,
  809.                     sizeof (short),
  810.                     &actualSize
  811.                 );
  812.         return (status);
  813. }
  814.  
  815. /*
  816.  * AEGetLong extracts an signed short integer from the parameter list.
  817.  */
  818. pascal OSErr
  819. AEGetLong(
  820.         const AppleEvent        *theEvent,
  821.         DescType                parameterKey,
  822.         long                    *result
  823.     )
  824. {
  825.         OSErr                    status;
  826.         Size                    actualSize;
  827.         DescType                actualType;
  828.  
  829.         status = AEGetParamPtr(
  830.                     theEvent,
  831.                     parameterKey,
  832.                     typeInteger,
  833.                     &actualType,
  834.                     (Ptr) result,
  835.                     sizeof (long),
  836.                     &actualSize
  837.                 );
  838.         return (status);
  839. }
  840.  
  841. /*
  842.  * AEGetBoolean extracts a Boolean from the parameter list.
  843.  */
  844. pascal OSErr
  845. AEGetBoolean(
  846.         const AppleEvent        *theEvent,
  847.         DescType                parameterKey,
  848.         Boolean                    *result
  849.     )
  850. {
  851.         OSErr                    status;
  852.         Size                    actualSize;
  853.         DescType                actualType;
  854.         
  855.         status = AEGetParamPtr(
  856.                     theEvent,
  857.                     parameterKey,
  858.                     typeBoolean,
  859.                     &actualType,
  860.                     (Ptr) result,
  861.                     sizeof (Boolean),
  862.                     &actualSize
  863.                 );
  864.         return (status);
  865. }
  866.  
  867. /*
  868.  * GetAEChars extracts a text item from the parameter list, returning it in a
  869.  * newly-allocated CharsHandle. The caller must dispose the handle.
  870.  */
  871. pascal OSErr
  872. AEGetChars(
  873.         const AppleEvent        *theEvent,
  874.         DescType                parameterKey,
  875.         CharsHandle                *result
  876.     )
  877. {
  878.         OSErr                    status;
  879.         AEDesc                    theDesc;
  880.  
  881.         status = AEGetParamDesc(
  882.                         theEvent,
  883.                         parameterKey,
  884.                         typeChar,
  885.                         &theDesc
  886.                     );
  887.         if (status == noErr)
  888.             *result = (CharsHandle) theDesc.dataHandle;
  889.         return (status);
  890. }
  891.  
  892. /*
  893.  * GetAEString extracts a Str255 from the parameter list.
  894.  */
  895. pascal OSErr
  896. AEGetString(
  897.         const AppleEvent        *theEvent,
  898.         DescType                parameterKey,
  899.         StringPtr                result
  900.     )
  901. {
  902.         OSErr                    status;
  903.         Size                    actualSize;
  904.         DescType                actualType;
  905.  
  906.         status = AEGetParamPtr(
  907.                     theEvent,
  908.                     parameterKey,
  909.                     typeChar,
  910.                     &actualType,
  911.                     (Ptr) &result[1],
  912.                     sizeof (Str255) - 1,
  913.                     &actualSize
  914.                 );
  915.         result[0] = actualSize;
  916.         return (status);
  917. }
  918.  
  919. /*
  920.  * AEPutShort stores a short integer into an AppleEvent reply.
  921.  */
  922. pascal OSErr
  923. AEPutShort(
  924.         AppleEvent                *theReply,
  925.         DescType                parameterKey,
  926.         short                    value
  927.     )
  928. {
  929.         OSErr                    status;
  930.         
  931.         status = AEPutParamPtr(
  932.                     theReply,
  933.                     parameterKey,
  934.                     typeSMInt,
  935.                     (Ptr) &value,
  936.                     sizeof value
  937.                 );
  938.         return (status);
  939. }
  940.  
  941. /*
  942.  * AEPutBoolean stores a Boolean into the AppleEvent reply.
  943.  */
  944. pascal OSErr
  945. AEPutBoolean(
  946.         AppleEvent                *theReply,
  947.         DescType                parameterKey,
  948.         Boolean                    value
  949.     )
  950. {
  951.         OSErr                    status;
  952.         
  953.         status = AEPutParamPtr(
  954.                     theReply,
  955.                     parameterKey,
  956.                     typeBoolean,
  957.                     (Ptr) &value,
  958.                     sizeof value
  959.                 );
  960.         return (status);
  961. }
  962.  
  963. /*
  964.  * AEPutLong stores a long integer into the AppleEvent reply.
  965.  */
  966. pascal OSErr
  967. AEPutLong(
  968.         AppleEvent                *theReply,
  969.         DescType                parameterKey,
  970.         long                    value
  971.     )
  972. {
  973.         OSErr                    status;
  974.         
  975.         status = AEPutParamPtr(
  976.                     theReply,
  977.                     parameterKey,
  978.                     typeInteger,
  979.                     (Ptr) &value,
  980.                     sizeof value
  981.                 );
  982.         return (status);
  983. }
  984.  
  985. /*
  986.  * AEPutStringHandle stores a StringHandle into the AppleEvent reply.
  987.  */
  988. pascal OSErr
  989. AEPutStringHandle(
  990.         AppleEvent                *theReply,
  991.         DescType                parameterKey,
  992.         const StringHandle        value
  993.     )
  994. {
  995.         OSErr                    status;
  996.         short                    lockState;
  997.         
  998.         lockState = HGetState((Handle) value);
  999.         HLock((Handle) value);
  1000.         status = AEPutString(theReply, parameterKey, *value);
  1001.         HSetState((Handle) value, lockState);
  1002.         return (status);
  1003. }
  1004.  
  1005. /*
  1006.  * AEPutCharsHandle stores a CharsHandle into the AppleEvent reply.
  1007.  */
  1008. pascal OSErr
  1009. AEPutCharsHandle(
  1010.         AppleEvent                *theReply,
  1011.         DescType                parameterKey,
  1012.         const CharsHandle        value
  1013.     )
  1014. {
  1015.         OSErr                    status;
  1016.         short                    lockState;
  1017.         
  1018.         lockState = HGetState((Handle) value);
  1019.         HLock((Handle) value);
  1020.         status = AEPutParamPtr(
  1021.                     theReply,
  1022.                     parameterKey,
  1023.                     typeChar,
  1024.                     (Ptr) *value,
  1025.                     GetHandleSize((Handle) value)
  1026.                 );
  1027.         HSetState((Handle) value, lockState);
  1028.         return (status);
  1029. }
  1030.  
  1031.  
  1032. /*
  1033.  * AEPutString stores a Str255 into the AppleEvent reply.
  1034.  */
  1035. pascal OSErr
  1036. AEPutString(
  1037.         AppleEvent                *theReply,
  1038.         DescType                parameterKey,
  1039.         ConstStr255Param        value
  1040.     )
  1041. {
  1042.         OSErr                    status;
  1043.         
  1044.         status = AEPutParamPtr(
  1045.                     theReply,
  1046.                     parameterKey,
  1047.                     typeChar,
  1048.                     (Ptr) &value[1],
  1049.                     value[0]
  1050.                 );
  1051.         return (status);
  1052. }
  1053.  
  1054. /*
  1055.  * Local function for AELocateTarget
  1056.  */
  1057. static void
  1058. AEGetMyZone(
  1059.         Str32                    zoneName
  1060.     )
  1061. {
  1062.         XPPParamBlock            pb;
  1063.         OSErr                    status;
  1064. #define PB    (pb)
  1065. #define kXPPTimeout                3
  1066. #define kXPPRetry                4
  1067.  
  1068.         CLEAR(PB);
  1069.         PB.XCALL.xppTimeout = kXPPTimeout;
  1070.         PB.XCALL.xppRetry = kXPPRetry;
  1071.         PB.XCALL.zipBuffPtr = (Ptr) zoneName;
  1072.         PB.XCALL.zipInfoField[0] = 0;
  1073.         PB.XCALL.zipInfoField[1] = 0;
  1074.         status = GetMyZone(&PB, FALSE);
  1075.         if (status == noBridgeErr) {
  1076.             zoneName[0] = 1;
  1077.             zoneName[1] = '*';
  1078.         }
  1079.         else if (status != noErr) {
  1080.             zoneName[0] = 0;
  1081.         }
  1082. #undef PB
  1083. }
  1084.  
  1085. static void
  1086. ClearMemory(
  1087.         void                    *dataPtr,
  1088.         register long            size
  1089.     )
  1090. {
  1091.         register char            *ptr;
  1092.  
  1093.         ptr = (char *) dataPtr;
  1094.         while (size > 0) {
  1095.             *ptr++ = 0;
  1096.             --size;
  1097.         }
  1098. }
  1099.  
  1100. static void
  1101. pstrcpy(
  1102.         StringPtr                dst,
  1103.         ConstStr255Param        src
  1104.     )
  1105. {
  1106.         BlockMoveData(src, dst, src[0] + 1);
  1107. }
  1108.  
  1109. static void
  1110. pstrcat(
  1111.         StringPtr                dst,
  1112.         ConstStr255Param        src
  1113.     )
  1114. {
  1115.         short                    length;
  1116.         
  1117.         length = 255 - dst[0];
  1118.         if (length > src[0])
  1119.             length = src[0];
  1120.         BlockMoveData(&src[1], &dst[1] + dst[0], length);
  1121.         dst[0] += length;
  1122. }
  1123.  
  1124.